/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.common.base.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.constants.ConstantVars;
import com.je.common.base.constants.StatusType;
import com.je.common.base.entity.func.FuncInfo;
import com.je.common.base.entity.func.FuncQueryStrategy;
import com.je.common.base.exception.PlatformException;
import com.je.common.base.exception.PlatformExceptionEnum;
import com.je.common.base.mapper.query.ConditionEnum;
import com.je.common.base.mapper.query.NativeQuery;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.*;
import com.je.common.base.service.impl.move.AbstractMoveService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.service.rpc.DataSecretRpcServive;
import com.je.common.base.spring.SpringContextHolder;
import com.je.common.base.util.MessageUtils;
import com.je.common.base.util.StringUtil;
import com.je.common.base.util.SystemSecretUtil;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.ibatis.extension.plugins.pagination.Page;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 实现平台基础功能
 *
 * @author wangmm@ketr.com.cn
 * @date 2019/12/6
 */
@Service
public class PlatformServiceImpl implements PlatformService {

    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaResourceService metaResourceService;
    @Autowired
    private CommonService commonService;
    @Autowired
    private QueryBuilderService queryBuilder;
    @Autowired
    private BeanService beanService;
    @Autowired
    private DataSecretRpcServive dataSecretRpcServive;

    @Override
    public Page load(BaseMethodArgument param, HttpServletRequest request) {
        if (param.getLimit() == 0) {
            param.setLimit(-1);
        }

        //分页对象
        Page page = new Page<>(param.getPage(), param.getLimit());

        String funcCode = param.getFuncCode();

        //构建查询条件
        ConditionsWrapper wrapper = buildWrapper(param, request);

        List<Map<String, Object>> list = metaService.load(funcCode, page, wrapper);
        page.setRecords(list);
        return page;
    }

    @Override
    public DynaBean doSave(BaseMethodArgument param, HttpServletRequest request) {
        //获取新增数据
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        //设置系统字段默认值
        commonService.buildModelCreateInfo(dynaBean);
        // 构建编号
        String codeGenFieldInfo = getStringParameter(request, "codeGenFieldInfo");
        if (StringUtil.isNotEmpty(codeGenFieldInfo)) {
            commonService.buildCode(codeGenFieldInfo, dynaBean);
        }
        String funcCode = getStringParameter(request, "funcCode");

        if (StringUtil.isNotEmpty(funcCode)) {
            DynaBean funcInfo = metaResourceService.selectOneByNativeQuery("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode));
            String funcType = funcInfo.getStr("FUNCINFO_FUNCTYPE");
            if ("VIEW".equals(funcType)) {
                //处理视图保存
                commonService.doViewData(funcCode, dynaBean, funcInfo);
            } else {
                dynaBean = commonService.doSave(dynaBean);
            }
        } else {
            dynaBean = commonService.doSave(dynaBean);
        }


        //单根树或多根树处理//todo 普通保存判断有没有树形子功能 是否多跟树 多跟树主功能新增数据同步新增子功能root节点
        //检测子功能是否增加ROOT节点 (子功能多树)
        commonService.doChildrenTree(dynaBean, funcCode);
        //处理单附件多附件上传
        commonService.doSaveFileMetadata(dynaBean, param.getBatchFilesFields(), param.getUploadableFields(), param.getFuncCode());

        //如果是操作视图，则数据重新查询
        String viewTableCode = getStringParameter(request, "viewTableCode");
        if (StringUtil.isNotEmpty(viewTableCode)) {
            String pkName = beanService.getPKeyFieldNamesByTableCode(viewTableCode);
            String pkVal = dynaBean.getStr(pkName);
            if (StringUtil.isNotEmpty(pkVal)) {
                if (Strings.isNullOrEmpty(dynaBean.getPkCode())) {
                    throw new PlatformException("未找到主键，请在资源表中，更换主键信息！", PlatformExceptionEnum.UNKOWN_ERROR);
                }
                dynaBean = metaService.selectOne(viewTableCode, ConditionsWrapper.builder().eq(dynaBean.getPkCode(), pkVal));
            }
        }
        return dynaBean;
    }

    @Override
    public DynaBean doCopy(BaseMethodArgument param, HttpServletRequest request) {
        if (StringUtil.isEmpty(param.getPkValue())) {
            throw new PlatformException("传入原记录主键失败", PlatformExceptionEnum.UNKOWN_ERROR);
        }
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        dynaBean.set(dynaBean.getPkCode(), param.getPkValue());
        //级联复制记录
        DynaBean copy = commonService.doCopy(dynaBean, param.getFuncCode(), param.getCodeGenFieldInfo(), param.getUploadableFields());
        return copy;
    }

    @Override
    public DynaBean doUpdate(BaseMethodArgument param, HttpServletRequest request) {
        //处理视图保存
        String funcType = getStringParameter(request, "funcType");
        String funcCode = getStringParameter(request, "funcCode");
        //构建修改信息
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        commonService.buildModelModifyInfo(dynaBean);

        if (!commonService.validDynaBeanUpdatePerm(funcCode, dynaBean.getTableCode(), dynaBean.getPkCode(), dynaBean.getPkValue())) {
            throw new PlatformException("您没有此数据的更改权限！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        //处理单附件多附件上传
        commonService.doSaveFileMetadata(dynaBean, param.getBatchFilesFields(), param.getUploadableFields(), param.getFuncCode());
        if (StringUtil.isNotEmpty(funcCode)) {
            DynaBean funcInfo = metaResourceService.selectOneByNativeQuery("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode));
            funcType = funcInfo.getStr("FUNCINFO_FUNCTYPE");
            if ("VIEW".equals(funcType)) {
                //处理视图保存
                commonService.doViewData(funcCode, dynaBean, funcInfo);
            } else {
                metaService.update(dynaBean);
            }
        } else {
            //更新数据
            metaService.update(dynaBean);
        }
        //如果是操作视图，则数据重新查询
        String viewTableCode = getStringParameter(request, "viewTableCode");
        if (StringUtil.isNotEmpty(viewTableCode)) {
            String pkName = beanService.getPKeyFieldNamesByTableCode(viewTableCode);
            String pkVal = getStringParameter(request, pkName);
            if (StringUtil.isNotEmpty(pkVal)) {
                dynaBean = metaService.selectOneByPk(viewTableCode, pkVal);
            }
        }
        return dynaBean;
    }

    @Override
    public DynaBean doBatchUpdate(BaseMethodArgument param, HttpServletRequest request) {
        String funcCode = getStringParameter(request, "funcCode");
        //获取修改内容
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        //获取批量修改条件
        ConditionsWrapper wrapper = param.buildQuery().buildWrapper();

        if (!commonService.validDynaBeanListUpdatePerm(funcCode, dynaBean.getTableCode(), wrapper)) {
            throw new PlatformException("您没有此数据的更改权限！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        //如果有功能编码则使用功能过滤条件
        if (StringUtils.isNotBlank(param.getFuncCode()) && StringUtils.isNotBlank(param.getFuncId())) {
            wrapper = buildWrapper(param, request);
        }

        //校验是否有条件
        if (wrapper.getSql().trim().length() == 0) {
            throw new PlatformException("批量修改条件不能为空！", PlatformExceptionEnum.JE_CORE_DYNABEAN_UPDATE_ERROR);
        }

        //批量修改
        metaService.update(dynaBean, wrapper);
        return dynaBean;
    }

    @Override
    public int doRemove(BaseMethodArgument param, HttpServletRequest request) {
        String funcCode = getStringParameter(request, "funcCode");
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        String ids = param.getIds();
        if (StringUtil.isEmpty(param.getTableCode()) || StringUtil.isEmpty(ids)) {
            throw new PlatformException("参数错误", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        if (!commonService.validDynaBeanListDeletePerm(funcCode, dynaBean.getTableCode(), ConditionsWrapper.builder().in(dynaBean.getPkCode(), Splitter.on(",").splitToList(ids)))) {
            throw new PlatformException("您没有此数据的删除权限！", PlatformExceptionEnum.UNKOWN_ERROR);
        }
        /**
         * 检查数据中是否有流程状态为已启动、或者已完成的，如果有一个有则不允许删除
         */
        String[] idArr = ids.split(",");
        List<String> stringIds = Arrays.asList(idArr);
        List<DynaBean> dynaBeanList = metaService.select(param.getTableCode(), ConditionsWrapper.builder().in(dynaBean.getPkCode(), stringIds));
        if (dynaBeanList != null && !dynaBeanList.isEmpty()) {
            for (DynaBean bean : dynaBeanList) {
                String syAudflag = bean.getStr("SY_AUDFLAG");
                if (Strings.isNullOrEmpty(syAudflag)) {
                    continue;
                }
                if (!"NOSTATUS".equals(syAudflag)) {
                    throw new PlatformException("流程已启动不能被删除...", PlatformExceptionEnum.UNKOWN_ERROR);
                }
            }
        }
        /**
         * 如果是树形数据，检查被删除模块是否存在子模块
         */
        if (param.getDoTree()) {
            for (String id : idArr) {
                //TODO 更改查询
                List<DynaBean> tableList = metaService.select(param.getTableCode(), ConditionsWrapper.builder("SY_PARENT = {0}", id));
                if (tableList != null && tableList.size() > 0) {
                    throw new PlatformException("请先删除模块下的子模块", PlatformExceptionEnum.UNKOWN_ERROR);
                }
            }
        }

        //级联删除子功能
        commonService.removeChild(param.getFuncCode(), param.getTableCode(), dynaBean.getPkCode(), param.getIds(), param.getDoTree());
        //删除该功能下的文档数据和文件
        if (param.getDoTree()) {
            commonService.doRemoveTreeBatchFiles(param.getTableCode(), param.getIds());
        } else {
            commonService.doRemoveBatchFiles(param.getTableCode(), param.getIds());
        }

        //视图级联配置 删除
        DynaBean funcinfo = metaResourceService.selectOneByNativeQuery("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode));
        String funcType = "";
        String viewConfigInfo = "";
        String viewTableCode = "";
        if (funcinfo != null) {
            funcType = funcinfo.getStr("FUNCINFO_FUNCTYPE");
            viewConfigInfo = funcinfo.getStr("FUNCINFO_VIEWCONFIGINFO");
            viewTableCode = funcinfo.getStr("FUNCINFO_TABLENAME");
        }

        int count = 0;
        if ("VIEW".equals(funcType)) {
            if (StringUtil.isNotEmpty(viewConfigInfo) && StringUtil.isNotEmpty(viewTableCode)) {
                String mainPkCode = beanService.getPKeyFieldNamesByTableCode(viewTableCode);
                count = commonService.doViewDelData(viewConfigInfo, viewTableCode, mainPkCode, param.getIds());
            } else {
                throw new PlatformException("请配置【视图操作表信息】后再执行删除！", PlatformExceptionEnum.UNKOWN_ERROR);
            }
        }

        //删除数据
        String[] idArray = param.getIds().split(",");
        if (param.getDoTree()) {
            ConditionsWrapper wrapper = ConditionsWrapper.builder();
            //删除当前节点及子节点
            wrapper.and(i -> {
                for (String id : idArray) {
                    i.like("SY_PATH", id);
                }
            }).or().in(dynaBean.getPkCode(), idArray);
            if (!"VIEW".equals(funcType)) {
                count = metaService.delete(param.getTableCode(), wrapper);
            }
            return count;
        } else {
            if (!"VIEW".equals(funcType)) {
                count = metaService.delete(param.getTableCode(), ConditionsWrapper.builder().in(dynaBean.getPkCode(), idArray));
            }
            return count;
        }
    }

    @Override
    public int doEnable(BaseMethodArgument param, HttpServletRequest request) {
        if (Strings.isNullOrEmpty(param.getTableCode()) || Strings.isNullOrEmpty(param.getIds())) {
            throw new PlatformException("参数错误", PlatformExceptionEnum.UNKOWN_ERROR);
        }
        String pkCode = beanService.getPKeyFieldNamesByTableCode(param.getTableCode());
        String funcCode = getStringParameter(request, "funcCode");

        if (!commonService.validDynaBeanListUpdatePerm(funcCode, param.getTableCode(), ConditionsWrapper.builder().in(pkCode, Splitter.on(",").splitToList(param.getIds())))) {
            throw new PlatformException("您没有此数据的更改权限！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        return metaService.executeSql("update " + param.getTableCode() + " set SY_STATUS = {0} where " + pkCode + " in ({1})", StatusType.ENABLED, param.getIds().split(","));
    }

    @Override
    public int doDisable(BaseMethodArgument param, HttpServletRequest request) {
        if (Strings.isNullOrEmpty(param.getTableCode()) || Strings.isNullOrEmpty(param.getIds())) {
            throw new PlatformException("参数错误", PlatformExceptionEnum.UNKOWN_ERROR);
        }
        String funcCode = getStringParameter(request, "funcCode");
        String pkCode = beanService.getPKeyFieldNamesByTableCode(param.getTableCode());
        if (!commonService.validDynaBeanListUpdatePerm(funcCode, param.getTableCode(), ConditionsWrapper.builder().in(pkCode, Splitter.on(",").splitToList(param.getIds())))) {
            throw new PlatformException("您没有此数据的更改权限！", PlatformExceptionEnum.UNKOWN_ERROR);
        }

        return metaService.executeSql("update " + param.getTableCode() + " set SY_STATUS = {0} where " + pkCode + " in ({1})", StatusType.DISABLED, param.getIds().split(","));

    }

    @Override
    public int doUpdateList(BaseMethodArgument param, HttpServletRequest request) {
        String funcType = getStringParameter(request, "funcType");
        String funcCode = getStringParameter(request, "funcCode");
        String updatesels = getStringParameter(request, "updatesels");
        // 构建编号
        String codeGenFieldInfo = param.getCodeGenFieldInfo();
        if (!Strings.isNullOrEmpty(updatesels) && "0".equals(updatesels)) {
            return commonService.doUpdateAllList(param.getTableCode(), funcType, funcCode, ((DynaBean) request.getAttribute("dynaBean")).getValues(), param, request);
        } else {
            List<DynaBean> updateList = commonService.doUpdateList(param.getTableCode(), param.getStrData(), funcType, funcCode, codeGenFieldInfo);
            return updateList.size();
        }
    }

    @Override
    public List<DynaBean> doUpdateListAndReturn(BaseMethodArgument param, HttpServletRequest request) {
        String funcType = getStringParameter(request, "funcType");
        String funcCode = getStringParameter(request, "funcCode");
        // 构建编号
        String codeGenFieldInfo = param.getCodeGenFieldInfo();
        return commonService.doUpdateList(param.getTableCode(), param.getStrData(), funcType, funcCode, codeGenFieldInfo);
    }

    @Override
    public DynaBean getInfoById(BaseMethodArgument param, HttpServletRequest request) {
        String pkValue = param.getPkValue();
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        if (StringUtil.isEmpty(pkValue)) {
            pkValue = dynaBean.getPkValue();
        }
        if (StringUtil.isEmpty(pkValue)) {
            return null;
        }
        String tableCode = dynaBean.getStr(BeanService.KEY_TABLE_CODE);
        if (StringUtil.isEmpty(tableCode)) {
            tableCode = param.getTableCode();
        }
        DynaBean selectOne = metaService.selectOneByPk(tableCode, pkValue);
        return selectOne;
    }

    @Override
    public JSONTreeNode getTree(BaseMethodArgument param, HttpServletRequest request) {
        String node = getStringParameter(request, "node");
        String tableCode = getStringParameter(request, "tableCode");
        String productId = getStringParameter(request, "SY_PRODUCT_ID") == null ? "" : getStringParameter(request, "SY_PRODUCT_ID");
        String async = getStringParameter(request, "async");
        JSONTreeNode template = beanService.getTreeTemplate(tableCode);

        if (StringUtils.isEmpty(node)) {
            node = ConstantVars.TREE_ROOT;
        }

        //构建查询条件
        Query query = param.buildQuery();
        if (!"ROOT".equals(node)) {
            query.addCustom("SY_PATH", ConditionEnum.LIKE, node);
        }
        if ("1".equals(async)) {
            query.addCustom("SY_PARENT", ConditionEnum.EQ, node);
        }

        //产品信息
        if (!Strings.isNullOrEmpty(productId)) {
            query.addCustom("SY_PRODUCT_ID", ConditionEnum.EQ, productId);
        }

        String orderSql = query.buildOrder();
        if (StringUtils.isBlank(orderSql)) {
            query.addOrder(template.getTreeOrderIndex(), "asc");
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                query.addOrder(template.getOrderIndex(), "asc");
            }
        }
        param.setjQuery(JSON.toJSONString(query));
        ConditionsWrapper wrapper = buildWrapper(param, request);

        List<Map<String, Object>> list = metaService.selectSql(wrapper.table(tableCode));

        //获取树形表数据
        boolean isAsync = "1".equals(async) ? true : false;
        List<JSONTreeNode> jsonTreeNodeList = commonService.buildJsonTreeNodeList(template, list, null, null, isAsync);
        //构建ROOT节点
        return commonService.buildJSONNewTree(jsonTreeNodeList, node);
    }

    @Override
    public List<Map<String, Object>> loadGridTree(BaseMethodArgument param, HttpServletRequest request) {
        //功能code，表code
        String funcCode = param.getFuncCode();
        String tableCode = param.getTableCode();
        String syProductId = getStringParameter(request, "SY_PRODUCT_ID");

        //获取根节点ID
        String node = param.getNode();
        if (StringUtils.isEmpty(node)) {
            node = ConstantVars.TREE_ROOT;
        }
        if (StringUtils.isNotEmpty(param.getRootId())) {
            node = param.getRootId();
        }
        DynaBean dynaBean = (DynaBean) request.getAttribute("dynaBean");
        if (param.getMoreRoot()) {
            //获取根节点ID
            String pkName = dynaBean.getStr(BeanService.KEY_PK_CODE);
            // TODO param.getParentSql() + " and SY_NODETYPE='ROOT'"
            String jParent = getStringParameter(request, "j_parent");
            Query parent = new Query();
            if (StringUtil.isNotEmpty(jParent)) {
                parent = Query.build(jParent);
            }
            DynaBean root = metaService.selectOne(tableCode, parent.buildWrapper().eq("SY_NODETYPE", "ROOT"));
            if (root != null) {
                node = root.getStr(pkName);
            } else {
                return null;
            }
        }
        //构建查询条件
        Query query = param.buildQuery();
        if (StringUtil.isNotEmpty(syProductId)) {
            query.addCustom("SY_PRODUCT_ID", ConditionEnum.EQ, syProductId);
        }
        //功能相关配置
        if (StringUtils.isNotBlank(funcCode)) {
            //获取功能配置
            FuncInfo funcInfo = commonService.functionConfig(funcCode);
            query.setFuncWhereSql(funcInfo.getOrderSql());
        }
        // TODO ExpandSql
//        if(StringUtil.isNotEmpty(param.getExpandSql())){
//            whereSql+=param.getExpandSql();
//        }

        boolean checked = "1".equals(param.getChecked()) || "true".equalsIgnoreCase(param.getChecked());

        //查询树形数据
        List<Map<String, Object>> records = commonService.loadGridTree(node, tableCode, param.getExcludes(), checked, query);
        if (param.getLimit() > 0) {
            Integer endIndex = param.getStart() + param.getLimit();
            if (endIndex >= records.size()) {
                endIndex = records.size();
            }
            records = records.subList(param.getStart(), endIndex);
        }
        return records;
    }

    @Override
    public String checkFieldUnique(BaseMethodArgument param, HttpServletRequest request) {
        String strData = param.getStrData();
        String funcCode = param.getFuncCode();
        String pkValue = param.getPkValue();
        DynaBean funcInfo = metaResourceService.selectOneByNativeQuery("JE_CORE_FUNCINFO", NativeQuery.build().eq("FUNCINFO_FUNCCODE", funcCode));
        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME");
        if (StringUtil.isNotEmpty(strData)) {
            JSONArray jsonArray = JSON.parseArray(strData);
            for (int i = 0; i < jsonArray.size(); i++) {
                DynaBean dynaBean = new DynaBean();
                dynaBean.table(tableCode);
                if (StringUtil.isNotEmpty(pkValue)) {
                    dynaBean.put(dynaBean.getPkCode(), pkValue);
                }
                Query query = param.buildQuery();
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                String fieldCode = jsonObject.getString("fieldCode");
                Object value = jsonObject.get("value");
                if (StringUtil.isNotEmpty(value)) {
                    dynaBean.set(fieldCode, value);
                    Boolean result = commonService.checkFieldUnique(dynaBean, fieldCode, query);
                    if (!result) {
                        return "字段[" + fieldCode + "],违反唯一约束!";
                    }
                }
            }
        }
        return null;
    }

    @Override
    public void executeDataFlow(List<String> dataFlowIdList, HttpServletRequest request) {
        List<DynaBean> dataFlows = metaResourceService.selectByTableCodeAndNativeQuery("JE_CORE_DATAFLOW", NativeQuery.build().in("JE_CORE_DATAFLOW_ID", dataFlowIdList));
        for (DynaBean dataFlow : dataFlows) {
            String sql = dataFlow.getStr("DATAFLOW_SQL");
            if (StringUtils.isNotBlank(sql)) {
                metaService.executeSql(sql);
            }
        }
    }

    @Override
    public DynaBean move(DynaBean parameter) {
        String tableCode = parameter.getTableCode();
        String id = parameter.getStr("id");
        String toId = parameter.getStr("toId");
        String place = parameter.getStr("place");
        String beanName = "";
        DynaBean fromBean = metaService.selectOneByPk(tableCode, id);
        DynaBean toResource = metaService.selectOneByPk(tableCode, toId);
        if (null == toResource) {
            throw new PlatformException(MessageUtils.getMessage("table.move.notNode"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
        }
        if ("JE_CORE_RESOURCETABLE".equals(tableCode)) {
            String type = toResource.getStr("RESOURCETABLE_TYPE");
            if (place.equals(AbstractMoveService.INSIDE) && !(type.equals("MODULE") || type.equals("ROOT"))) {
                throw new PlatformException(MessageUtils.getMessage("table.move.onlyModule"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
            }
        }
        if ("JE_CORE_MENU".equals(tableCode)) {
            String type = toResource.getStr("MENU_NODEINFOTYPE");
            if (place.equals(AbstractMoveService.INSIDE) && !(type.equals("MENU") || type.equals("ROOT"))) {
                throw new PlatformException(MessageUtils.getMessage("table.move.onlyModule"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
            }
        }
        String path = toResource.getStr("SY_PATH");
        if (path.indexOf(id) >= 0) {
            throw new PlatformException(MessageUtils.getMessage("table.move.onlyChildModule"), PlatformExceptionEnum.JE_CORE_TABLE_UPDATE_ERROR);
        }
        if (place.equals(AbstractMoveService.ABOVE)) {
            beanName = "moveAboveService";
        }

        if (place.equals(AbstractMoveService.BELOW)) {
            beanName = "moveBelowService";
        }
        //获取最后一个，变成放到最后一个资源的下面
        if (place.equals(AbstractMoveService.INSIDE)) {
            beanName = "moveInsideService";
            String parent = toResource.getPkValue();
            List<DynaBean> list = metaService.select(tableCode, 0, 1,
                    ConditionsWrapper.builder().eq("SY_PARENT", parent).orderByDesc("SY_ORDERINDEX"));
            if (list.size() > 0) {
                toResource = list.get(0);
                beanName = "moveBelowService";
            }
        }

        MoveService moveService = SpringContextHolder.getBean(beanName);
        moveService.move(tableCode, id, toId, fromBean, toResource);
        return null;
    }

    @Override
    public List<Map<String, Object>> statistics(BaseMethodArgument param, HttpServletRequest request) {
        List<Map<String, Object>> result = new ArrayList();
        ConditionsWrapper wrapper = buildWrapper(param, request);
        String strData = param.getStrData();
        JSONObject strJsonData = JSONObject.parseObject(strData);
        StringBuffer sbSql = new StringBuffer();
        sbSql.append("SELECT ");
        for (String code : strJsonData.keySet()) {
            JSONArray types = strJsonData.getJSONArray(code);
            for (int i = 0; i < types.size(); i++) {
                String sqlType = StatisticsEnum.getSqlTypeByStatisticsType(types.getString(i));
                if (Strings.isNullOrEmpty(sqlType)) {
                    continue;
                }
                if (sbSql.length() > 7) {
                    sbSql.append(",");
                }
                //SUM( SY_TENANT_ID ) AS SY_TENANT_ID_JE_STATISTICS_SUM
                sbSql.append(String.format(" %s(%s) AS %s_JE_STATISTICS_%s ", sqlType, code, code, types.getString(i)));
            }
        }
        sbSql.append(" FROM ");
        sbSql.append(param.getTableCode() + " ");

        if (!Strings.isNullOrEmpty(wrapper.getParameterSql()) && !(wrapper.getParameterSql().toUpperCase().trim().startsWith("ORDER"))) {
            sbSql.append(" WHERE " + wrapper.getParameterSql());
        }
        List<Map<String, Object>> list = metaService.selectSql(sbSql.toString());
        if (list.size() == 0) {
            return result;
        }

        Map<String, Object> selectResultMap = list.get(0);
        for (String code : strJsonData.keySet()) {
            Map<String, Object> map = new HashMap<>();
            map.put("code", code);
            JSONArray types = strJsonData.getJSONArray(code);
            for (int i = 0; i < types.size(); i++) {
                Object value = selectResultMap.get(String.format("%s_JE_STATISTICS_%s", code, types.getString(i)));
                if (value == null) {//配合前端处理msg的问题
                    map.put(types.getString(i), "");
                } else {
                    map.put(types.getString(i), value);
                }
            }
            result.add(map);
        }
        return result;
    }

    private void appendSecretInfo(ConditionsWrapper wrapper) {
        if (!SystemSecretUtil.isOpen()) {
            return;
        }
        //如果开启了密级
        DynaBean tableBean = beanService.getResourceTable(wrapper.getTable());
        List<DynaBean> columns = tableBean.getDynaBeanList(BeanService.KEY_TABLE_COLUMNS);
        boolean secret = false;
        for (DynaBean eachColumn : columns) {
            if ("SY_SECRET_CODE".equals(eachColumn.getStr("TABLECOLUMN_CODE"))) {
                secret = true;
                break;
            }
        }
        if (secret) {
            List<String> secretCodeList = dataSecretRpcServive.requireContextDataSecretLevel();
            wrapper.in("SY_SECRET_CODE", secretCodeList);
        }
    }
    @Override
    public int batchModifyListData(BaseMethodArgument param, HttpServletRequest request) {
        String funcCode = param.getFuncCode();
        String tableCode = request.getParameter("tableCode");
        //构建查询条件
        ConditionsWrapper wrapper = buildWrapper(param, request);
        String bean = request.getParameter("bean");
        if (Strings.isNullOrEmpty(bean)) {
            return 0;
        }
        JSONObject beanObject = JSONObject.parseObject(bean);

        Map<String, Object> beanMap = beanObject;
        DynaBean dynaBean = new DynaBean(tableCode, true);
        String pkCode = dynaBean.getPkCode();
        dynaBean.getValues().putAll(beanMap);
        dynaBean.put(BeanService.KEY_TABLE_CODE, tableCode);
        String type = request.getParameter("type");
        //批量修改
        if (type.equals("query")) {
            String totalCount = request.getParameter("totalCount");
            if (param.getLimit() == 0) {
                param.setLimit(-1);
            }
            //分页对象
            Page page = new Page<>(param.getPage(), param.getLimit());
            List<Map<String, Object>> list = metaService.load(funcCode, page, wrapper);
            //校验   前端传过来的修改数量是否和后台查询的数量一致。
            if (!Strings.isNullOrEmpty(totalCount) && (list.size() != Integer.parseInt(totalCount))) {
                throw new PlatformException("批量修改失败，校验数据不一致，请刷新缓存后重试！", PlatformExceptionEnum.JE_CORE_CONTROLLER_ERROR);
            }
            return metaService.update(dynaBean, wrapper);
        } else if (type.equals("select")) {
            String ids = param.getIds();
            if (Strings.isNullOrEmpty(ids)) {
                throw new PlatformException("ids信息不能为空！", PlatformExceptionEnum.JE_CORE_CONTROLLER_ERROR);
            }
            String[] idsArray = ids.split(",");
            return metaService.update(dynaBean, ConditionsWrapper.builder().in(pkCode, idsArray));
        }
        return 0;
    }


    @Override
    public ConditionsWrapper buildWrapper(BaseMethodArgument param, HttpServletRequest request) {
        //功能code，表code
        String funcCode = param.getFuncCode();
        String tableCode = param.getTableCode();

        //获取查询条件
        Query query = param.buildQuery();
        query.setFuncId(param.getFuncId());
        query.setFuncCode(funcCode);

        //此段代码会使树构建失败
//        if (!Strings.isNullOrEmpty(funcCode)) {
//            FuncInfo funcInfo = commonService.functionConfig(funcCode);
//            String treeFuncConfig = funcInfo.getTreeFuncConfig();
//            if (!Strings.isNullOrEmpty(treeFuncConfig)) {
//                JSONArray treeConfigArray = JSONObject.parseArray(treeFuncConfig);
//                for (int i = 0; i < treeConfigArray.size(); i++) {
//                    if (!"moreRoot".equals(treeConfigArray.getJSONObject(i).getString("key"))) {
//                        continue;
//                    }
//                    if (treeConfigArray.getJSONObject(i).getBoolean("value")) {
//                        query.addCustom("SY_NODETYPE", ConditionEnum.NE, "ROOT");
//                    }
//                }
//            }
//        }

        //设置是否覆盖功能whereSql
        query.setOverrideFuncWhere("1".equals(getStringParameter(request, "coverJquery")));
        query.setSyProductId(getStringParameter(request, "SY_PRODUCT_ID"));

        //功能相关配置
        if (StringUtils.isNotBlank(funcCode)) {
            //获取功能配置
            FuncInfo funcInfo = commonService.functionConfig(funcCode);
            query.setFuncId(funcInfo.getFuncId());
            query.setFuncPkCode(funcInfo.getPkCode());
            query.setFuncWhereSql(funcInfo.getWhereSql());
            query.setFuncOrderSql(funcInfo.getOrderSql());

            //获取查询策略
            if (StringUtils.isNotBlank(query.getStrategyId())) {
                FuncQueryStrategy strategy = null;
                //查找缓存中的查询策略
                if (funcInfo.getStrategies() != null) {
                    List<FuncQueryStrategy> strategiesFilter = funcInfo.getStrategies().stream()
                            .filter(p -> query.getStrategyId().equals(p.getId())).collect(Collectors.toList());
                    if (!strategiesFilter.isEmpty()) {
                        strategy = strategiesFilter.get(0);
                    }
                }
                //数据库查找查询策略
                if (strategy == null) {
                    //7.封装查询策略
                    DynaBean queryStrategy = metaResourceService.selectOneByNativeQuery("JE_CORE_QUERYSTRATEGY", NativeQuery.build().eq("JE_CORE_QUERYSTRATEGY_ID", query.getStrategyId()));
                    if (queryStrategy != null) {
                        strategy = new FuncQueryStrategy(queryStrategy.getStr("JE_CORE_QUERYSTRATEGY_ID"), queryStrategy.getStr("QUERYSTRATEGY_SQL"), queryStrategy.getStr("QUERYSTRATEGY_FGGNSQL"));
                    }
                }
                query.setStrategyBean(strategy);
            }
        }

        ConditionsWrapper wrapper = ConditionsWrapper.builder().table(tableCode);
        appendSecretInfo(wrapper);

        //设置条件
        wrapper = queryBuilder.buildWrapper(query,wrapper);
        wrapper.function(funcCode).table(tableCode).selectColumns(param.getQueryColumns());


        return wrapper;
    }

}